

from core.himesis import Himesis, HimesisPostConditionPattern
import cPickle as pickle
from uuid import UUID

class HMoveOneBackwardLinkDiffRulesRHS(HimesisPostConditionPattern):
    def __init__(self):
        """
        Creates the himesis graph representing the AToM3 model HMoveOneBackwardLinkDiffRulesRHS.
        """
        # Flag this instance as compiled now
        self.is_compiled = True
        
        super(HMoveOneBackwardLinkDiffRulesRHS, self).__init__(name='HMoveOneBackwardLinkDiffRulesRHS', num_nodes=14, edges=[])
        
        # Add the edges
        self.add_edges([(7, 2), (2, 5), (6, 3), (3, 4), (1, 4), (12, 0), (13, 0), (0, 1), (6, 11), (7, 10), (10, 8), (8, 12), (11, 9), (9, 13)])
        # Set the graph attributes
        self["mm__"] = pickle.loads("""(lp1
S'MT_post__SimpleDSLTransMM'
p2
aS'MoTifRule'
p3
a.""")
        self["MT_action__"] = pickle.loads("""V#===============================================================================\u000a# This code is executed after the rule has been applied.\u000a# You can access a node labelled n matched by this rule by: PostNode('n').\u000a# To access attribute x of node n, use: PostNode('n')['x'].\u000a#===============================================================================\u000a\u000apass\u000a
p1
.""")
        self["name"] = """"""
        self["GUID__"] = UUID('d2a753d9-9c01-4da3-8593-8395c2ac38dc')
        
        # Set the node attributes
        self.vs[0]["MT_label__"] = """5"""
        self.vs[0]["MT_post__name"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[0]["mm__"] = """MT_post__MetaModelElement_T"""
        self.vs[0]["MT_post__classtype"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[0]["GUID__"] = UUID('d7bcf0bc-64b4-4cc2-8483-4c43ab219955')
        self.vs[1]["MT_label__"] = """23"""
        self.vs[1]["mm__"] = """MT_post__backward_link"""
        self.vs[1]["GUID__"] = UUID('d63b626d-d454-4e32-af83-00e236f56dc4')
        self.vs[2]["MT_label__"] = """16"""
        self.vs[2]["mm__"] = """MT_post__match_contains"""
        self.vs[2]["GUID__"] = UUID('26a8a153-0f35-4779-870e-10b9f59c1ca8')
        self.vs[3]["MT_label__"] = """20"""
        self.vs[3]["mm__"] = """MT_post__match_contains"""
        self.vs[3]["GUID__"] = UUID('5ad365b7-cdaf-45a6-b9df-924d5f179439')
        self.vs[4]["MT_pivotOut__"] = """element1"""
        self.vs[4]["MT_label__"] = """4"""
        self.vs[4]["MT_post__name"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[4]["mm__"] = """MT_post__MetaModelElement_S"""
        self.vs[4]["MT_post__classtype"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[4]["GUID__"] = UUID('909e37db-0701-4bfb-ab62-81fc311d1ffd')
        self.vs[5]["MT_pivotOut__"] = """element2"""
        self.vs[5]["MT_label__"] = """6"""
        self.vs[5]["MT_post__name"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[5]["mm__"] = """MT_post__MetaModelElement_S"""
        self.vs[5]["MT_post__classtype"] = """
#===============================================================================
# You can access the value of the current node's attribute value by: attr_value.
# If the current node shall be created you MUST initialize it here!
# You can access a node labelled n by: PreNode('n').
# To access attribute x of node n, use: PreNode('n')['x'].
# Note that the attribute values are those before the match is rewritten.
# The order in which this code is executed depends on the label value
# of the encapsulating node.
# The given action must return the new value of the attribute.
#===============================================================================

return attr_value
"""
        self.vs[5]["GUID__"] = UUID('1823d4ce-7bf3-4844-9c85-01a0998e72a8')
        self.vs[6]["MT_label__"] = """1"""
        self.vs[6]["mm__"] = """MT_post__MatchModel"""
        self.vs[6]["GUID__"] = UUID('9ff79313-bb1a-488d-ad20-f4b0cbfc9df8')
        self.vs[7]["MT_label__"] = """2"""
        self.vs[7]["mm__"] = """MT_post__MatchModel"""
        self.vs[7]["GUID__"] = UUID('c4f16673-c1f9-4b2d-b44a-db5f08246c21')
        self.vs[8]["MT_label__"] = """3"""
        self.vs[8]["mm__"] = """MT_post__ApplyModel"""
        self.vs[8]["GUID__"] = UUID('dd9f5f8b-79b3-4ffa-b779-29cd9ddbbca6')
        self.vs[9]["MT_label__"] = """7"""
        self.vs[9]["mm__"] = """MT_post__ApplyModel"""
        self.vs[9]["GUID__"] = UUID('ad8b0e41-5bf9-47df-9c7a-34bcf0192eec')
        self.vs[10]["MT_label__"] = """13"""
        self.vs[10]["mm__"] = """MT_post__paired_with"""
        self.vs[10]["GUID__"] = UUID('1209ff69-1c06-4492-8965-a2e35c2ac9fe')
        self.vs[11]["MT_label__"] = """22"""
        self.vs[11]["mm__"] = """MT_post__paired_with"""
        self.vs[11]["GUID__"] = UUID('913a55c9-d791-4394-8dcf-3afcccb9f42c')
        self.vs[12]["MT_label__"] = """15"""
        self.vs[12]["mm__"] = """MT_post__apply_contains"""
        self.vs[12]["GUID__"] = UUID('5640733b-f403-48b4-aff8-6066c1b72561')
        self.vs[13]["MT_label__"] = """14"""
        self.vs[13]["mm__"] = """MT_post__apply_contains"""
        self.vs[13]["GUID__"] = UUID('a8f43de4-ee38-4c11-a048-8cc0bfd0ebc4')

        from HMoveOneBackwardLinkDiffRulesLHS import HMoveOneBackwardLinkDiffRulesLHS
        self.pre = HMoveOneBackwardLinkDiffRulesLHS()
    
    def action(self, PostNode, graph):
        """
            Executable constraint code. 
            @param PostNode: Function taking an integer as parameter
                             and returns the node corresponding to that label.
        """
        #===============================================================================
        # This code is executed after the rule has been applied.
        # You can access a node labelled n matched by this rule by: PostNode('n').
        # To access attribute x of node n, use: PostNode('n')['x'].
        #===============================================================================
        
        pass

    def execute(self, packet, match):
        """
            Transforms the current match of the packet according to the rule %s.
            Pivots are also assigned, if any.
            @param packet: The input packet.
            @param match: The match to rewrite.
        """
        graph = packet.graph
        
        # Build a dictionary {label: node index} mapping each label of the pattern to a node in the graph to rewrite.
        # Because of the uniqueness property of labels in a rule, we can store all LHS labels
        # and subsequently add the labels corresponding to the nodes to be created.
        labels = match.copy()
        
        #===============================================================================
        # Update attribute values
        #===============================================================================
        
        #===============================================================================
        # Create new nodes
        #===============================================================================
        # backward_link23
        new_node = graph.add_node()
        labels['23'] = new_node
        graph.vs[new_node][Himesis.Constants.META_MODEL] = 'backward_link'
        # apply_contains14
        new_node = graph.add_node()
        labels['14'] = new_node
        graph.vs[new_node][Himesis.Constants.META_MODEL] = 'apply_contains'
        
        #===============================================================================
        # Create new edges
        #===============================================================================
        # apply_contains14 -> MetaModelElement_T5
        graph.add_edges((labels['14'], labels['5']))
        # ApplyModel7 -> apply_contains14
        graph.add_edges((labels['7'], labels['14']))
        # backward_link23 -> MetaModelElement_S4
        graph.add_edges((labels['23'], labels['4']))
        # MetaModelElement_T5 -> backward_link23
        graph.add_edges((labels['5'], labels['23']))
        
        #===============================================================================
        # Set the output pivots
        #===============================================================================
        # MetaModelElement_S4
        packet.global_pivots['element1'] = graph.vs[labels['4']][Himesis.Constants.GUID]
        # MetaModelElement_S6
        packet.global_pivots['element2'] = graph.vs[labels['6']][Himesis.Constants.GUID]
        
        #===============================================================================
        # Perform the post-action
        #===============================================================================
        try:
            self.action(lambda i: graph.vs[labels[i]], graph)
        except Exception, e:
            raise Exception('An error has occurred while applying the post-action', e)
        #===============================================================================
        # Finally, delete nodes (this will automatically delete the adjacent edges)
        #===============================================================================
        # MT_pre__backward_link17
        graph.delete_nodes([labels["17"]])
    
